#include <asm-generic/errno-base.h>
#include <errno.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  sem_t *sem_arr[2];
  sem_arr[0] = sem_open("a", O_CREAT, 0666, 0);
  if (sem_arr[0] == SEM_FAILED) {
    perror("sem_open fail");
    exit(-1);
  }

  sem_arr[1] = sem_open("b", O_CREAT, 0666, 1);
  if (sem_arr[1] == SEM_FAILED) {
    perror("sem_open fail");
    exit(-1);
  }

  key_t key = ftok(".", 1);
  if (key < 0) {
    perror("ftok fail");
    exit(-1);
  }

  int shm_id = shmget(key, 1024, IPC_CREAT | IPC_EXCL | 0666);
  if (shm_id < 0 && errno == EEXIST) {
    shm_id = shmget(key, 1024, 0666);
  }

  char *shm_buf = shmat(shm_id, NULL, 0);
  if (shm_buf == (void *)-1) {
    perror("shmat fail");
    exit(-1);
  }

  while (1) {
    sem_wait(sem_arr[0]);
    printf("please input:");
    memset(shm_buf, 0, 1024);
    scanf("%s", shm_buf);
    sem_post(sem_arr[1]);
    if (!strcmp("bye", shm_buf))
      break;
  }

  sem_close(sem_arr[0]);
  shmdt(shm_buf);
  shmctl(shm_id, IPC_RMID, NULL);
  sem_unlink("a");
  sem_unlink("b");
  return 0;
}
